package cl.interpreter;

import java.util.ArrayList;
import java.util.List;

public class Environment {
    
    private List<Variable> variables;
    private Environment parentEnv;
    
    public Environment(Environment parent) {
        this.parentEnv = parent;
        variables = new ArrayList<Variable>();
    }
    
    public void addVariable(Variable variable) throws DuplicateVariableException {
        for(Variable v : variables) {
            if(v.getName().equals(variable.getName())) {
                throw new DuplicateVariableException("Trying to create duplicate variable: " + variable.getName());
            }
        }
        variables.add(variable);
    }
    
    public void setVariable(String variableName, Object value) throws NonExistantVariableException, IncorrectTypeException {
        for(Variable v : variables) {
            if(v.getName().equals(variableName)) {
                v.setValue(value);
                return;
            }
        }
        
        if(parentEnv != null) {
            parentEnv.setVariable(variableName, value);
        } else {
            throw new NonExistantVariableException("Trying to assign to unknown variable: " + variableName);
        }
    }
    
    public boolean hasVariable(String variableName) {
        for(Variable v : variables) {
            if(v.getName().equals(variableName)) {
                return true;
            }
        }
        
        if(parentEnv != null) {
            return parentEnv.hasVariable(variableName);
        } else {
            return false;
        }
    }
    
    public String getVariableType(String variableName) {
        for(Variable v : variables) {
            if(v.getName().equals(variableName)) {
                return v.getType();
            }
        }
        
        if(parentEnv != null) {
            return parentEnv.getVariableType(variableName);
        } else {
            return null;
        }
    }
    
    public Object getVariableValue(String variableName) {
        for(Variable v : variables) {
            if(v.getName().equals(variableName)) {
                return v.getValue();
            }
        }
        
        if(parentEnv != null) {
            return parentEnv.getVariableValue(variableName);
        } else {
            return null;
        }
    }
}
